import java.io.IOException;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;

/**
 * Created with IntelliJ IDEA.
 * Description:客户端代码
 * User: wx
 * Date: 2024-03-14
 * Time: 13:21
 */
public class UdpEchoClient {
    private DatagramSocket socket = null;
    private String serveIp;
    private int servePort;


    //此处ip使用字符串,点分十进制风格."192.168.2.2.100"
    public UdpEchoClient(String serveIP, int servePort) throws SocketException {
        this.serveIp = serveIP;
        this.servePort = servePort;
        socket = new DatagramSocket();
    }

    public void start() throws IOException {
        System.out.println("客户端启动");
        Scanner scanner = new Scanner(System.in);
        while (true) {
            System.out.printf("-> ");
            //做四个事情
            // 1.从控制台读取要发送的请求数据.
            if(!scanner.hasNext()){
                break;
            }
           String request = scanner.next();
            // 2.构造一个请求并发送.
            DatagramPacket requestPacket = new DatagramPacket(request.getBytes(), request.getBytes().length,
                    InetAddress.getByName(serveIp), servePort);
            socket.send(requestPacket);
            // 3.读取服务器的响应.
            DatagramPacket responsePacket = new DatagramPacket(new byte[4096],4096);
            socket.receive(responsePacket);
            // 4.把这个响应显示到控制台上./
            String response = new String(responsePacket.getData(),0,responsePacket.getLength());
            System.out.println(response);
        }
    }

    public static void main(String[] args) throws IOException {
        UdpEchoClient client = new UdpEchoClient("127.0.0.1",9090);
        client.start();
    }
}


//服务器这边,需要指定端口号
// 但是在客户端这边,不手动指定,也有端口,系统自动分配一个空闲的端口号
// 代码中指定端口号,才能确定端口号始终是固定的
// 如果不手动指定,依赖系统分配,导致服务器每次重启之后,端口号可能会变
// ---------------------------------------------------------
// 为什么客户端要指定端口号?
// 端口号一旦改变,客户端可能找不到服务器
// 为什么不指定客户端端口号?
// 客户端来说,端口号让系统随机分配,系统分配一个空闲的
// 主要是无发确保手动指定的端口号,是可用的
//----------------------------------------------------------
// 服务器端口就不会被占用?只担心客户端?
// 服务器是在我们手里的,是可控的,我们可以事先知道服务器有那些端口被使用
// 客户端是在普通用户的机器上,普通用户千千万,上边的环境也千差万别,不知道用户装了一些什么程序,
// 导致端口被占用.从而引起端口绑定失败而无法启动


// public UdpEchoClient(String serveIP, int servsPort) throws SocketException {
//        socket = new DatagramSocket();
//    }
//   客户端需要主动给服务器发送请求.发起请求的前提是需要知道服务器在哪里
//   String serveIP, int servePort
//   请求的目的IP 和 目的端口 就是上边这两个参数了
//   请求的源IP 就是客户端的本机ip,源端口就是系统分配的空闲端口/

// String request = scanner.next();
// 从控制台读取,如果使用 scanner 读取字符串,最好使用 next 而不是 nextLine
// 如果使用 nextLine 读取,需要手动输入换行符 enter来进行控制
// 由于 enter键不仅仅会产生\n还会产生其他字符,就会导致读取到的其他内容就容易出问题
// 使用next 其实是以"空白符"作为分隔符,包括不限于 换行,回车,空格,制表符,垂直制表符
// 从文件读取.就不牵扯了/





// 第一种,构造的时候指定空白的字节数组(搭配 receive)
// DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);
//
// 第二种,构造的时候指定一个有内容的字节数组,并且指定ID 和 端口(发数据的时候使用)
// DatagramPacket responsePcket = new DatagramPacket(response.getBytes(), response.getBytes().length,
//        requestPacket.getSocketAddress());
//
// 第三种,构造的时候,指定有内容的字节数组,并且指定 ip 和 端口.ip和端口分开指定(发数据的时候使用)
// DatagramPacket requestPacket = new DatagramPacket(request.getBytes(), request.getBytes().length,
//                    InetAddress.getByName(serveIp), servePort);
//
//             /